﻿using UnityEngine;
using UnityEditor;
using System.Collections;
using System.IO;
using System.Linq;

namespace DoomWad
{
	public class WadMapImporterWindow : EditorWindow
	{
		public const string WAD_DIR = "../wad/";

		private const string NOWAD = "[NO-WAD]";

		private int selectedWadIndex = 0;
		private int selectedMapIndex = 0;

		WadMapImporter dmi = new WadMapImporter();
		private float scale = 1f;
		private FilterMode textureFilter = FilterMode.Point;
		private bool makeSkyMask = false;

		private string[] wadpathes = new string[ 1 ] { NOWAD };
		private string[] mapnames = new string[ 1 ] { NOWAD };
		private string wadpath = "";

		[MenuItem( "Window/Doom WAD Map Importer" )]
		[MenuItem( "Assets/Doom WAD Map Importer" )]
		private static void ShowWindow()
		{
			WadMapImporterWindow editor = GetWindow( typeof( WadMapImporterWindow ), false, "Doom WAD" ) as WadMapImporterWindow;
			editor.UpdateWadList();
		}

		private void UpdateWadList()
		{
			if ( Directory.Exists( WAD_DIR ) )
			{
				wadpathes = AssetUtils.FindFilesByFilter( WAD_DIR, "*.wad" );
				if ( wadpathes.Length == 0 )
					wadpathes = new string[ 1 ] { NOWAD };
			}
			else
			{
				wadpathes = new string[ 1 ] { NOWAD };
			}
			
			selectedWadIndex = Mathf.Clamp( selectedWadIndex, 0, wadpathes.Length - 1 );
			if ( selectedWadIndex >= 0 && selectedWadIndex < wadpathes.Length )
			{
				wadpath = wadpathes[ selectedWadIndex ];
				UpdateMapList( wadpathes[ selectedWadIndex ] );
			}
		}

		private void UpdateMapList( string wadpath )
		{
			if ( wadpath == NOWAD )
			{
				mapnames = new string[ 0 ];
			}
			else
			{
				WadReader wad = new WadReader( wadpath );
				mapnames = wad.GetMapList();
			}

			selectedMapIndex = Mathf.Clamp( selectedMapIndex, 0, mapnames.Length - 1 );
		}

		void OnProjectChange()
		{
			UpdateWadList();
		}

		void OnGUI()
		{
			EditorGUILayout.BeginVertical();

			//--------------------------------------------------------------------
			// Wad
			//--------------------------------------------------------------------

			EditorGUILayout.LabelField( "Wad", EditorStyles.boldLabel );

			// Мануально "Обновить список wad-ов"
			if ( GUILayout.Button( "Update Wad List" ) )
				UpdateWadList();

			// Выводим имя/путь активного файла
			EditorGUI.BeginChangeCheck();
			selectedWadIndex = Mathf.Clamp( selectedWadIndex, 0, wadpathes.Length - 1 );
			selectedWadIndex = EditorGUILayout.Popup( "Wad File", selectedWadIndex, wadpathes );
			if ( EditorGUI.EndChangeCheck() )
			{
				wadpath = wadpathes[ selectedWadIndex ];
				UpdateMapList( wadpath );
			}

			// Проверяем нужно ли выводить helpbox

			bool isexist = false;
			if ( wadpath != NOWAD )
				isexist = File.Exists( wadpath );

			if ( !isexist )
			{
				EditorGUILayout.HelpBox(
					"В папке "+ WAD_DIR + " нет ни одного файла с типом *.wad",
					MessageType.Warning, true );
				EditorGUILayout.EndVertical();
				return;
			}
			
			if ( !WadReader.CheckWadFile( wadpath ) )
			{
				EditorGUILayout.HelpBox(
					"Тип файла не является IWAD или PWAD.",
					MessageType.Warning, true );
				EditorGUILayout.EndVertical();
				return;
			}

			//--------------------------------------------------------------------
			// Maps
			//--------------------------------------------------------------------

			EditorGUILayout.LabelField( "" );
			EditorGUILayout.LabelField( "Map", EditorStyles.boldLabel );

			// Выводим список карт

			selectedMapIndex = EditorGUILayout.Popup( "Map", selectedMapIndex, mapnames );

			// Параметры

			dmi.scale = EditorGUILayout.FloatField( "Map Scale", dmi.scale );
			dmi.textureFilter = ( FilterMode ) EditorGUILayout.EnumPopup( "Texture Filter", dmi.textureFilter );
			dmi.makeColliders = EditorGUILayout.Toggle( "Make Colliders", dmi.makeColliders );

			dmi.makeSkyMask = EditorGUILayout.Toggle( "Make Sky Mask", dmi.makeSkyMask );
			if ( dmi.makeSkyMask )
				EditorGUILayout.HelpBox( "Sky mask - это меш потолка секторов с открытым верхом. " +
					"Маска неба имеет специальный материал, за которым не видно геометрии, а только skybox", MessageType.Info );
			
			dmi.makeTextureAssets = EditorGUILayout.Toggle( "Make Texture Assets", dmi.makeTextureAssets );
			if ( dmi.makeTextureAssets )
				EditorGUILayout.HelpBox( "Создание ассетов текстур значительно снижает скорость импорта", MessageType.Info );

			//--------------------------------------------------------------------
			// Lightmapping
			//--------------------------------------------------------------------
			
			EditorGUILayout.LabelField( "" );
			EditorGUILayout.LabelField( "Lightmapping", EditorStyles.boldLabel );

			dmi.generateLightmapUV = EditorGUILayout.Toggle( "Generate Lightmap UVs", dmi.generateLightmapUV );
			dmi.generateIllumMaterials = EditorGUILayout.Toggle( "Generate Illum Materials", dmi.generateIllumMaterials );
			if ( dmi.generateIllumMaterials )
			{
				dmi.illumEmission = EditorGUILayout.FloatField( "Illum Emission", dmi.illumEmission );
				dmi.allAreIllum = EditorGUILayout.Toggle( "All Are Illum", dmi.allAreIllum );
				if ( !dmi.allAreIllum )
				{
					EditorGUILayout.HelpBox( "Список частей имен текстур, которые будут трактоваться как 'излучаемые', задаются статической переменной illumTexNameParts класса " +
						typeof( WadMapImporter ).ToString(), MessageType.Info );
				}
			}


			//--------------------------------------------------------------------
			// Import/Clear
			//--------------------------------------------------------------------

			EditorGUILayout.LabelField( "" );

			// Импортируем мапу
			if ( GUILayout.Button( "Import" ) )
				dmi.Import( wadpath, mapnames[ selectedMapIndex ] );

			// Очистка
			if ( GUILayout.Button( "Clear" ) )
				Clear();

			//--------------------------------------------------------------------
			// Debug
			//--------------------------------------------------------------------

			EditorGUILayout.LabelField( "" );
			EditorGUILayout.LabelField( "Debug", EditorStyles.boldLabel );

			EditorGUILayout.HelpBox( "See logfile_editor.txt", MessageType.Info );

			if ( GUILayout.Button( "Print Lump Table" ) )
			{
				WadReader reader = new WadReader( wadpath );
				reader.PrintLumpList();
				Log.Close();
			}

			if ( GUILayout.Button( "Print Wall Textures" ) )
			{
				WadReader reader = new WadReader( wadpath );
				reader.PrintMapTextures();
				Log.Close();
			}

			EditorGUILayout.EndVertical();
		}

		void OnSelectionChange()
		{
			Repaint();
		}

		private void Clear()
		{
			foreach ( string mapname in mapnames )
			{
				GameObject go = GameObject.Find( mapname );
				while ( go )
				{
					GameObject.DestroyImmediate( go );
					go = GameObject.Find( mapname );
				};
			}
		}

		private void PrintSelectedFiles()
		{
			GUILayout.Label( "Selected Files:", EditorStyles.boldLabel );

			foreach ( Object o in Selection.objects )
			{
				GUILayout.Label( AssetDatabase.GetAssetPath( o ) );
			}
		}
	}
}